﻿#include <iostream>
#include <cmath>
#include <windows.h>  // Windows系统用于控制台操作
#include <vector>

using namespace std;

// 控制台相关的常量定义
const int CONSOLE_WIDTH = 80;   // 控制台宽度
const int CONSOLE_HEIGHT = 40;  // 控制台高度
const double PI = 3.14159265359; // 圆周率

// 设置控制台光标位置的函数
void setCursorPosition(int x, int y) {
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

// 清屏函数
void clearScreen() {
    system("cls");
}

// 隐藏光标函数
void hideCursor() {
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    cursorInfo.bVisible = false;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

// 爱心的数学方程类
class Heart {
private:
    double scale;        // 缩放因子
    double offsetX;      // X轴偏移
    double offsetY;      // Y轴偏移
    double timeOffset;   // 时间偏移，用于动画效果

public:
    // 构造函数：初始化爱心参数
    Heart(double s = 1.0, double ox = CONSOLE_WIDTH / 2, double oy = CONSOLE_HEIGHT / 2)
        : scale(s), offsetX(ox), offsetY(oy), timeOffset(0) {
    }

    // 爱心的参数方程
    // 使用极坐标方程：x = 16sin³(t), y = 13cos(t) - 5cos(2t) - 2cos(3t) - cos(4t)
    pair<int, int> getHeartPoint(double t) {
        // 计算爱心的X坐标：16 * sin³(t)
        double x = 16 * pow(sin(t), 3);

        // 计算爱心的Y坐标：13cos(t) - 5cos(2t) - 2cos(3t) - cos(4t)
        double y = 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t);

        // 应用缩放和偏移，并调整坐标系（Y轴翻转，因为控制台坐标系Y轴向下）
        int screenX = (int)(offsetX + x * scale);
        int screenY = (int)(offsetY - y * scale);

        return make_pair(screenX, screenY);
    }

    // 更新时间偏移，用于创建动画效果
    void updateAnimation(double deltaTime) {
        timeOffset += deltaTime;
    }

    // 获取当前的动画缩放因子（心跳效果）
    double getAnimationScale() {
        // 使用正弦函数创建心跳效果：基础大小 + 心跳变化
        return 0.8 + 0.3 * sin(timeOffset * 2); // 3是心跳频率
    }

    // 获取动画颜色变化（用于彩色心脏）
    int getAnimationColor() {
        // 根据时间改变颜色，创建彩虹效果
        int colorIndex = (int)(timeOffset * 2) % 6;
        return colorIndex + 1; // 返回1-6的颜色代码
    }
};

// 在指定位置打印字符，并设置颜色
void printAtPosition(int x, int y, char ch, int color = 7) {
    // 检查坐标是否在控制台范围内
    if (x >= 0 && x < CONSOLE_WIDTH && y >= 0 && y < CONSOLE_HEIGHT) {
        setCursorPosition(x, y);

        // 设置文字颜色（Windows控制台颜色代码）
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hConsole, color);

        cout << ch;
    }
}

// 绘制爱心的函数
void drawHeart(Heart& heart) {
    double currentScale = heart.getAnimationScale();
    int currentColor = heart.getAnimationColor();

    // 遍历参数t从0到2π，绘制完整的爱心
    for (double t = 0; t < 2 * PI; t += 0.1) {
        // 创建临时爱心对象，应用当前的动画缩放
        Heart tempHeart(currentScale, CONSOLE_WIDTH / 2, CONSOLE_HEIGHT / 2 - 5);
        pair<int, int> point = tempHeart.getHeartPoint(t);

        // 在计算出的位置打印心形字符
        printAtPosition(point.first, point.second, '*', 12); // 12是红色
    }

    // 在爱心周围添加一些装饰性的小星星
    for (double t = 0; t < 2 * PI; t += 0.3) {
        Heart outerHeart(currentScale * 1.3, CONSOLE_WIDTH / 2, CONSOLE_HEIGHT / 2 - 5);
        pair<int, int> point = outerHeart.getHeartPoint(t);

        // 随机决定是否在该位置显示小星星
        if (rand() % 3 == 0) {
            printAtPosition(point.first, point.second, '.', currentColor + 8);
        }
    }
}

// 显示浪漫的文字信息
void displayMessage() {
    // 在屏幕底部显示浪漫信息
    setCursorPosition(CONSOLE_WIDTH / 2 - 10, CONSOLE_HEIGHT - 5);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 13); // 粉红色
    cout << "❤ Forever Love ❤";

    setCursorPosition(CONSOLE_WIDTH / 2 - 15, CONSOLE_HEIGHT - 3);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14); // 黄色
    cout << "Press ESC to exit...";
}

// 检查是否按下了ESC键
bool isEscPressed() {
    return GetAsyncKeyState(VK_ESCAPE) & 0x8000;
}

// 主函数
int main() {
    // 设置控制台属性
    hideCursor();           // 隐藏光标
    clearScreen();          // 清屏

    // 创建爱心对象
    Heart heart;

    // 动画循环变量
    double time = 0;
    const double timeStep = 0.05; // 时间步长，控制动画速度

    cout << "动态爱心动画启动中..." << endl;
    cout << "按ESC键退出程序" << endl;
    Sleep(2000); // 等待2秒

    // 主动画循环
    while (!isEscPressed()) {
        clearScreen(); // 清除上一帧

        // 更新心脏动画
        heart.updateAnimation(timeStep);

        // 绘制当前帧的爱心
        drawHeart(heart);

        // 显示文字信息
        displayMessage();

        // 在屏幕顶部显示一些装饰文字
        setCursorPosition(CONSOLE_WIDTH / 2 - 8, 2);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11); // 浅蓝色
        cout << "💖 Dynamic Heart 💖";

        // 更新时间
        time += timeStep;

        // 控制帧率（大约20 FPS）
        Sleep(100); // 暂停50毫秒
    }

    // 程序结束时的清理工作
    clearScreen();
    setCursorPosition(0, 0);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); // 恢复默认颜色
    cout << "感谢使用动态爱心程序！再见！" << endl;

    return 0;
}